package com.alien.admin.modules.deploy.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alien.admin.context.task.TaskQueue;
import com.alien.admin.exception.BadRequestException;
import com.alien.admin.modules.basic.domain.ReplicaSet;
import com.alien.admin.modules.basic.service.JenkinsService;
import com.alien.admin.modules.basic.service.K8sService;
import com.alien.admin.modules.basic.utils.K8sTemplateGenerator;
import com.alien.admin.modules.container.service.K8sProjectService;
import com.alien.admin.modules.container.service.dto.K8sProjectQueryCriteria;
import com.alien.admin.modules.deploy.domain.*;
import com.alien.admin.modules.deploy.repository.*;
import com.alien.admin.modules.deploy.service.DeployRecService;
import com.alien.admin.modules.deploy.service.DeployService;
import com.alien.admin.modules.deploy.service.DpEnvVariablesService;
import com.alien.admin.modules.deploy.service.ServerPortService;
import com.alien.admin.modules.deploy.service.dto.*;
import com.alien.admin.modules.deploy.service.mapstruct.DeployRecMapper;
import com.alien.admin.modules.gitlab.service.GitlabService;
import com.alien.admin.modules.gitlab.service.dto.MergeBranch;
import com.alien.admin.modules.gitlab.service.utils.EnvUtils;
import com.alien.admin.modules.publisher.domain.PublishDeploy;
import com.alien.admin.modules.publisher.repository.PublishDeployRepository;
import com.alien.admin.modules.publisher.service.PublishSheetFlowService;
import com.alien.admin.modules.publisher.service.dto.PublishProjectDto;
import com.alien.admin.modules.publisher.service.dto.PublishSheetFlowDto;
import com.alien.admin.modules.publisher.service.mapstruct.PublishSheetFlowMapper;
import com.alien.admin.modules.security.service.dto.JwtUserDto;
import com.alien.admin.modules.system.service.UserService;
import com.alien.admin.modules.system.service.dto.UserDto;
import com.alien.admin.utils.*;
import org.gitlab4j.api.GitLabApiException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author: zsy
 * @Date: 2021/10/28 9:36
 */
@Service
public class DeployServiceImpl implements DeployService {

    @Autowired
    private GitlabService gitlabService;
    @Autowired
    private DpServerRepository dpServerRepository;
    @Autowired
    private DpServerConfigRepository dpServerConfigRepository;
    @Autowired
    private DpImageBuildTplRepository dpImageBuildTplRepository;
    @Autowired
    private DpDeployTplRepository dpDeployTplRepository;
    @Autowired
    private DeployRecService deployRecService;
    @Autowired
    private DeployRecRepository deployRecRepository;
    @Autowired
    private DpJenkinsInstanceRepository dpJenkinsInstanceRepository;
    @Autowired
    private DeployRecMapper deployRecMapper;
    @Autowired
    private JenkinsService jenkinsService;
    @Autowired
    private DpEnvVariablesService dpEnvVariablesService;
    @Autowired
    private DpK8sInstanceRepository dpK8sInstanceRepository;
    @Autowired
    private K8sService k8sService;
    @Autowired
    private TaskQueue taskQueue;
    @Autowired
    private ServerPortService serverPortService;
    @Autowired
    private UserService userService;
    @Autowired
    private PublishSheetFlowService publishSheetFlowService;
    @Autowired
    private PublishSheetFlowMapper publishSheetFlowMapper;
    @Autowired
    private EnvUtils envUtils;
    @Autowired
    private PublishDeployRepository publishDeployRepository;
    @Autowired
    private K8sProjectService k8sProjectService;

    private String mergeBranch(DeployRecQueryCriteria criteria) throws GitLabApiException {
        MergeBranch mereBrn = new MergeBranch();
        mereBrn.setEnv(criteria.getEnv());
        mereBrn.setSource(criteria.getSource());
        mereBrn.setProjectId(criteria.getProjectId().longValue());
        mereBrn.setEnableRollback(false);
        return gitlabService.mergeBranch(mereBrn);
    }

    private DeployRecDto deploy(String env, DpServer dpServer, String sourceBranch, String targetBranch) {
        Integer projectId = dpServer.getProjectId().intValue();

        // 项目属性
        DeployRec deployRec = new DeployRec();
        deployRec.setEnv(env);
        deployRec.setProjectId(projectId);
        deployRec.setProjectName(dpServer.getName());
        deployRec.setSourceBranch(sourceBranch);
        deployRec.setTargetBranch(targetBranch);

        String codeType = dpServer.getCodeType();

        validConfig(deployRec, projectId, env, codeType);
        return startDeploy(deployRec, projectId, env, codeType);
    }

    private void validConfig(DeployRec deployRec, Integer projectId, String env, String codeType) {
        // 根据框架类型，寻找部署模板id和构建模板id，如果找不到则报错
        DpImageBuildTpl dpImageBuildTpl = dpImageBuildTplRepository.findFirstByFrameworkTypeAndEnv(codeType, env);
        if (dpImageBuildTpl == null) {
            throw new BadRequestException("找不到框架类型为" + codeType + "的构建模板");
        }

        DpDeployTpl dpDeployTpl = dpDeployTplRepository.findFirstByEnv(env);
        if (dpDeployTpl == null) {
            throw new BadRequestException("找不到环境为" + env + "的容器部署模板");
        }

        // 校验服务配置
        DpServerConfig dpServerConfig = dpServerConfigRepository.findFirstByProjectIdAndEnv(projectId, env);
        if(dpServerConfig == null) {
            throw new BadRequestException("找不到该服务的配置信息!");
        }

//        if(StringUtils.isEmpty(dpServerConfig.getBuildParam()) && !codeType.equals("dockerfile")){
//            throw new BadRequestException("找不到该服务的镜像构建的配置信息!");
//        }
    }

    private DeployRecDto startDeploy(DeployRec deployRec, Integer projectId, String env, String codeType) {
        // 直接进入部署镜像步骤
        // 步骤 1-合并分支
        deployRec.setStage(DeployConstant.DEPLOY_STAGE_BUILD_IMAGE);
        // 构建状态 0-未构建
        deployRec.setDeployStatus(DeployConstant.DEPLOY_STATUS_NONE);

        DpServerConfig dpServerConfig = dpServerConfigRepository.findFirstByProjectIdAndEnv(projectId, env);
        deployRec.setBuildParam(dpServerConfig.getBuildParam());

        // 部署用户
        deployRec.setOperatorId(SecurityUtils.getCurrentUserId());
        Date date = new Date();
        deployRec.setDeployTime(new Timestamp(date.getTime()));

        // 根据框架类型，寻找部署模板id和构建模板id，如果找不到则报错
        DpImageBuildTpl dpImageBuildTpl = dpImageBuildTplRepository.findFirstByFrameworkTypeAndEnv(codeType, env);
        deployRec.setBuildTplId(dpImageBuildTpl.getId());
        deployRec.setJenkinsInstanceId(dpImageBuildTpl.getJenkinsId());

        DpDeployTpl dpDeployTpl = dpDeployTplRepository.findFirstByEnv(env);
        deployRec.setDeployTplId(dpDeployTpl.getId());

        // 保存构建参数
        deployRec.setBuildParam(dpServerConfig.getBuildParam());

        DeployRecDto deployRecDto = deployRecService.create(deployRec);

        //进入任务队列
        taskQueue.putTaskToQueue(deployRecDto.getId());

        return deployRecDto;
    }

    @Override
    public DeployRecDto createProjectDeploy(DeployRecQueryCriteria criteria) {
        Integer projectId = criteria.getProjectId();
        String env = criteria.getEnv();
        String sourceBranch = criteria.getSource();

        ValidationUtil.isNull(projectId, "DeployRecQueryCriteria", "projectId", projectId);
        ValidationUtil.isNull(env, "DeployRecQueryCriteria", "env", env);
        ValidationUtil.isNull(sourceBranch, "DeployRecQueryCriteria", "sourceBranch", sourceBranch);

        DpServer dpServer = dpServerRepository.findById(projectId.longValue()).get();
        if (dpServer == null) {
            throw new BadRequestException("找不到项目：id:" + projectId);
        }

        // 先进行代码合并
        String targetBranch = null;
        try {
            targetBranch = mergeBranch(criteria);
        } catch (GitLabApiException ex) {
            throw new BadRequestException(ex.getMessage());
        }

        return deploy(env, dpServer, sourceBranch, targetBranch);
    }

    void enabledDeployByFlow(Long flowId) {
        // 一笔申请单，同一个时间只能有一个部署流程
        List<PublishDeploy> publishDeployList = publishDeployRepository.queryAllByFlowIdAndStatus(flowId, PublishDeployConstant.PUBLISH_DEPLOYSTATUS_RUNNING);
        if(publishDeployList != null && !publishDeployList.isEmpty()) {
            throw new BadRequestException("当前已有部署流程，需等待上个流程结束才能部署!");
        }
    }

    @Override
    public void deployByFlow(PublishSheetFlowDto flowDto, String env) {
        enabledDeployByFlow(flowDto.getId());

        List<PublishProjectDto> projectDtoList = flowDto.getPublishProjects().stream().collect(Collectors.toList());

        // 获取流程发布者的gittoken
        Long applierId = flowDto.getApplierId();
        UserDto userDto = userService.findById(applierId);
        String gitlabToken = userDto.getGitlabToken();
        if(StringUtils.isEmpty(gitlabToken)) {
            throw new BadRequestException("申请者(" + userDto.getNickName() + ")的账号未设置gitlab的token");
        }

        // 获取项目列表，并且进行合并，所有项目的分支合并成功才允许部署，合并失败回退代码分支
        boolean merged = mergeBranch(projectDtoList, env, gitlabToken);
        if(!merged) {
            throw new BadRequestException("代码分支合并失败，请人工处理冲突后重新操作");
        }

        int projectLen = projectDtoList.size();
        // 先校验服务配置是否正确，省的部署后再来做回退
        List<DeployRec> preparedDeployRecList = new ArrayList<>(projectLen);
        for(int index = 0; index < projectLen; index++) {
            PublishProjectDto publishProjectDto = projectDtoList.get(index);
            Integer projectId = publishProjectDto.getProjectId().intValue();

            DpServer dpServer = dpServerRepository.findById(projectId.longValue()).orElseGet(DpServer::new);
            ValidationUtil.isNull(dpServer.getProjectId(), "dpServer", "projectId", projectId);

            // 项目属性
            // 获取待合并分支
            String sourceBranch = publishProjectDto.getBranch();
            String envBranchName = envUtils.getEnvStandardBranch(env);
            String codeType = dpServer.getCodeType();

            DeployRec deployRec = new DeployRec();
            deployRec.setEnv(env);
            deployRec.setProjectId(projectId);
            deployRec.setProjectName(dpServer.getName());
            deployRec.setSourceBranch(sourceBranch);
            deployRec.setTargetBranch(envBranchName);
            deployRec.setCodeType(codeType);

            validConfig(deployRec, projectId, env, codeType);

            // 添加到待部署列表
            preparedDeployRecList.add(deployRec);
        }

        Long deployNum = flowDto.getDeployNum() != null ? flowDto.getDeployNum().longValue() : 0;
        deployNum++;

        // 生成一筆审批单部署记录
        final JwtUserDto jwtUserDto = (JwtUserDto) SecurityUtils.getCurrentUser();
        PublishDeploy publishDeploy = new PublishDeploy();
        publishDeploy.setEnv(env);
        publishDeploy.setFlowId(flowDto.getId());
        publishDeploy.setFlowNum(deployNum);
        publishDeploy.setPublishTime(DateUtil.now());
        publishDeploy.setStage(PublishDeployConstant.PUBLISH_DEPLOYSTAGE_DEPLOY);
        publishDeploy.setStatus(PublishDeployConstant.PUBLISH_DEPLOYSTATUS_RUNNING);
        publishDeploy.setOperatorId(jwtUserDto.getUser().getId());
        publishDeploy.setOperatorName(jwtUserDto.getUser().getNickName());
        publishDeploy = publishDeployRepository.save(publishDeploy);
        Long publishDeployId = publishDeploy.getId().longValue();

        // 真正部署
        preparedDeployRecList.stream().forEach(preparedDeployRec -> {
            preparedDeployRec.setPublishDeployId(publishDeployId);
            startDeploy(preparedDeployRec, preparedDeployRec.getProjectId(), env, preparedDeployRec.getCodeType());
        });

        // 回写deployNum
        flowDto.setDeployNum(deployNum.intValue());
        publishSheetFlowService.update(publishSheetFlowMapper.toEntity(flowDto));
    }

    private boolean mergeBranch(List<PublishProjectDto> projectDtoList, String env, String gitlabToken) {
        int size = projectDtoList.size();
        for(int index = 0; index < size; index++) {
            PublishProjectDto projectDto = projectDtoList.get(index);

            MergeBranch mereBrn = new MergeBranch();
            mereBrn.setEnableRollback(true);
            mereBrn.setEnv(env);
            mereBrn.setSource(projectDto.getBranch());
            mereBrn.setProjectId(projectDto.getProjectId());

            try {
                gitlabService.mergeBranch(gitlabToken, mereBrn);
            } catch (Exception e) {
                e.printStackTrace();

                // 回退已经合并的项目
                for(int i = 0; i <= index; i++) {
                    PublishProjectDto project = projectDtoList.get(i);
                    try {
                        gitlabService.rollbackBranch(gitlabToken, project.getBranch(), env, project.getProjectId().intValue());
                    } catch (GitLabApiException ex) {
                        ex.printStackTrace();
                        throw new BadRequestException("合并代码失败:  " + e.getMessage());
                    }
                }
                return false;
            }
        }

        return true;
    }

    private String generateImageUrl(String imagePushUrl, String projectName) {
        SimpleDateFormat df = new SimpleDateFormat("yyyyMMddHHmmss");
        String imageVersion = df.format(new Date());

        // 镜像url不能带有大写字母
        String lowerProjectName = projectName.toLowerCase();
        String imageUrl = String.format("%s%s:%s", imagePushUrl, lowerProjectName, imageVersion);
        return imageUrl;
    }

    private String appendSystemParam(String projectName, String buildParam, DeployRec deployRec) {

        String imageUrl = deployRec.getBuildImageUrl();

        JSONObject jsonObject = JSON.parseObject(buildParam);
        jsonObject.put("PROJECT_NAME", projectName);
        jsonObject.put("BRANCH", deployRec.getTargetBranch());
        jsonObject.put("IMAGE_URL", imageUrl);

        String finialParam = jsonObject.toJSONString();
        return finialParam;
    }

    @Override
    public DeployRec buildImage(Long recId) {
        DeployRec deployRec = deployRecRepository.findById(recId).orElseGet(DeployRec::new);
        ValidationUtil.isNull(deployRec.getId(), "DeployRec", "id", deployRec.getId());

        String buildParam = deployRec.getBuildParam();
        buildParam = buildParam == null ? "{}" : buildParam;

        DpServer dpServer = dpServerRepository.findById(deployRec.getProjectId()
                .longValue()).get();

        // 附加系统参数
        // 获取构建模板
        DpImageBuildTpl dpImageBuildTpl = dpImageBuildTplRepository.findById(deployRec.getBuildTplId()).orElseGet(DpImageBuildTpl::new);
        ValidationUtil.isNull(dpImageBuildTpl.getId(), "DpImageBuildTpl", "id", dpImageBuildTpl.getId());
        ValidationUtil.isNull(dpImageBuildTpl.getImagePushUrl(), "DpImageBuildTpl", "imagePushUrl", dpImageBuildTpl.getImagePushUrl());

        // 生成镜像id
        String imageUrl = generateImageUrl(dpImageBuildTpl.getImagePushUrl(), dpServer.getName());
        deployRec.setBuildImageUrl(imageUrl);
        buildParam = appendSystemParam(dpServer.getName(), buildParam, deployRec);

        // 获取关联的jenkins实例
        Integer jenkinsInstanceId = deployRec.getJenkinsInstanceId();
        DpJenkinsInstance jenkinsInstance = dpJenkinsInstanceRepository.findById(jenkinsInstanceId).orElseGet(DpJenkinsInstance::new);
        ValidationUtil.isNull(jenkinsInstance.getId(), "DpJenkinsInstance", "id", jenkinsInstance.getId());

        String jobName = deployRec.getProjectName();
        // 判断job是否存在，不存在则创建
        boolean hasJob = jenkinsService.hasJob(jenkinsInstance, jobName);
        if (!hasJob) {
            String jobContent = dpImageBuildTpl.getContent();
            // 替换sshurl变量
            jobContent = jobContent.replace("{{ .GitSSHURL }}", dpServer.getSshUrl());

            boolean success = jenkinsService.createJob(jenkinsInstance, jobName, jobContent);
            if (!success) {
                // 构建成功，构建状态-》0-待部署1-部署中2-失败3-成功
                deployRec.setDeployStatus(DeployConstant.DEPLOY_STATUS_FAILED);
                return deployRecRepository.save(deployRec);
            }
        }

        Integer queueId = jenkinsService.buildJob(jenkinsInstance, jobName, buildParam);
        ValidationUtil.isEqual(queueId, -1L, "构建失败，请检查配置参数是否正确");

        // 构建成功，构建状态-》0-待部署1-部署中2-失败3-成功
        deployRec.setDeployStatus(DeployConstant.DEPLOY_STATUS_RUNNING);
        deployRec.setBuildQueueId(queueId.longValue());

        // 保存进数据库
        DeployRec imageDeployRec = deployRecRepository.save(deployRec);

        // 拉取jenkins日志加入任务池
        taskQueue.putTaskToQueue(deployRec.getId());

        return imageDeployRec;
    }

    Map<String, String> queryServerEnvList(Integer projectId, String env) {
        DpEnvVariablesQueryCriteria criteria = new DpEnvVariablesQueryCriteria();
        criteria.setEnv(env);

        // 全局环境变量
        List<DpEnvVariablesDto> globalVariablesDtoList = dpEnvVariablesService.queryAll(criteria);
        Map<String, String> globalVariables = globalVariablesDtoList.stream()
                .filter(globalVariablesDto -> globalVariablesDto.getProjectId() == null)
                .collect(Collectors.toMap(DpEnvVariablesDto::getName, DpEnvVariablesDto::getValue));

        // 服务环境变量
        criteria.setProjectId(String.valueOf(projectId));
        List<DpEnvVariablesDto> serverVariablesDtoList = dpEnvVariablesService.queryAll(criteria);
        Map<String, String> serverVariables = serverVariablesDtoList.stream()
                .collect(Collectors.toMap(DpEnvVariablesDto::getName, DpEnvVariablesDto::getValue));

        globalVariables.putAll(serverVariables);
        return globalVariables;
    }

    @Override
    public DeployRec deploy(Long recId) {
        DeployRec deployRec = deployRecRepository.findById(recId).orElseGet(DeployRec::new);
        ValidationUtil.isNull(deployRec.getId(), "DeployRec", "id", deployRec.getId());

        try {
            Integer deployTplId = deployRec.getDeployTplId();
            DpDeployTpl deployTpl = dpDeployTplRepository.findById(deployTplId).orElseGet(DpDeployTpl::new);
            ValidationUtil.isNull(deployTpl.getId(), "DpDeployTpl", "id", deployTpl.getId());

            deployRec.setDeployStatus(DeployConstant.DEPLOY_STATUS_NONE);

            // 获取部署模板
            // 镜像
            String imageUrl = deployRec.getBuildImageUrl();
            // 模板
            String deploymentTplContent = deployTpl.getContent();

            // 从服务配置表中获取模板、命名空间、集群id
            DpServerConfig dpServerConfig = dpServerConfigRepository.findFirstByProjectIdAndEnv(deployRec.getProjectId(), deployRec.getEnv());
            ValidationUtil.isNull(dpServerConfig.getId(), "DpServerConfig", "id", deployRec.getProjectId());

            // 获取服务的环境变量
            Map<String, String> envMap = queryServerEnvList(deployRec.getProjectId(), deployRec.getEnv());

            K8sTemplateGenerator k8sTemplateGenerator = new K8sTemplateGenerator(dpServerConfig, deploymentTplContent,
                    deployRec, envMap);

            Map<String, Object> userParamMap = new HashMap<>(5);
            String env = deployRec.getEnv();
            if(env.contains("debug") || env.contains("test")) {
                // 获取容器端口
                ServerPortDto serverPort = serverPortService.generateServerNodePort(deployRec.getProjectName(), deployRec.getEnv());
                userParamMap.put("nodePort", String.valueOf(serverPort.getPort()));
            }

            // 额外设置，例如灰度/节点数量/资源，覆盖默认配置
            String deployParamStr = deployRec.getDeployParam();
            userParamMap = appendDeployParamMap(userParamMap, deployParamStr);

            // 部署yml保存到数据库，以便查找问题
            String deploymentYmlText = k8sTemplateGenerator.generateYmlContent(userParamMap, imageUrl);
            deployRec.setDeployYml(deploymentYmlText);

            // 从dpServerConfig获取
            Integer k8sInstanceId = dpServerConfig.getK8sInstanceId();
            String namespace = dpServerConfig.getK8sNameSpace();

            DpK8sInstance k8sInstance = dpK8sInstanceRepository.findById(k8sInstanceId).orElseGet(DpK8sInstance::new);
            ValidationUtil.isNull(k8sInstance.getId(), "DpK8sInstance", "id", k8sInstance.getId());
            k8sService.deploy(k8sInstance, deploymentYmlText);

            // 保存进数据库
            deployRec.setDeployStatus(DeployConstant.DEPLOY_STATUS_RUNNING);
            deployRec.setK8SInstanceId(k8sInstanceId.intValue());
            deployRec.setNameSpace(namespace);

            // 获取当前运行的副本集名称，作为回滚之用
            K8sProjectQueryCriteria k8sProjectQueryCriteria = new K8sProjectQueryCriteria();
            k8sProjectQueryCriteria.setEnv(env);
            k8sProjectQueryCriteria.setProjectId(deployRec.getProjectId().longValue());
            ReplicaSet replicaSet = k8sProjectService.queryCurrentReplicaSet(k8sProjectQueryCriteria);
            if(replicaSet != null) {
                deployRec.setRollbackReplicaSetName(replicaSet.getName());
            }

            DeployRec k8sDeployRec = deployRecRepository.save(deployRec);

            taskQueue.putTaskToQueue(deployRec.getId());

            return k8sDeployRec;
        } catch (Exception e) {
            // 部署失败
            deployRec.setDeployStatus(DeployConstant.DEPLOY_STATUS_FAILED);
            return deployRecRepository.save(deployRec);
        }
    }

    Map<String, Object> appendDeployParamMap(Map<String, Object> userParamMap, String deployParamStr) throws java.io.IOException {
        if(StringUtils.isNotEmpty(deployParamStr)) {
            InputStream byteInputStream = new ByteArrayInputStream(deployParamStr.getBytes());
            Properties properties = new Properties();
            properties.load(byteInputStream);
            for(String key : properties.stringPropertyNames()) {
                String propertyValue = properties.getProperty(key);
                userParamMap.put(key, propertyValue);
            }
        }

        return userParamMap;
    }

    @Override
    public DeployRec deployByHistory(Long recId) {
        DeployRec deployRec = deployRecRepository.findById(recId).orElseGet(DeployRec::new);
        ValidationUtil.isNull(deployRec.getId(), "DeployRec", "id", recId);

        // 部署历史版本，直接拿历史镜像做部署，其他属性从历史记录拷贝
        DeployRec deployNowRec = new DeployRec();
        deployNowRec.copy(deployRec);

        deployNowRec.setId(null);
        deployNowRec.setDeployTime(Timestamp.valueOf(LocalDateTime.now()));
        deployNowRec.setStage(DeployConstant.DEPLOY_STAGE_DEPLOY);
        deployNowRec.setDeployStatus(DeployConstant.DEPLOY_STATUS_NONE);
        deployNowRec.setDeployLog("");
        DeployRec newDeployRec = deployRecRepository.save(deployNowRec);

        // 直接进入容器部署
        taskQueue.putTaskToQueue(newDeployRec.getId());

        return newDeployRec;
    }

    @Override
    public String queryLog(Integer projectId, String env) {
        DpServerConfig dpServerConfig = dpServerConfigRepository.findFirstByProjectIdAndEnv(projectId, env);
        if (dpServerConfig == null || StringUtils.isEmpty(dpServerConfig.getK8sNameSpace())) {
            throw new BadRequestException("请配置服务所部署的集群");
        }

        DpServer dpServer = dpServerRepository.findById(projectId.longValue()).get();
        if (dpServer == null) {
            throw new BadRequestException("找不到项目：id:" + projectId);
        }

        Integer k8sIntanceId = dpServerConfig.getK8sInstanceId();
        DpK8sInstance k8sInstance = dpK8sInstanceRepository.findById(k8sIntanceId).orElseGet(DpK8sInstance::new);
        ValidationUtil.isNull(k8sInstance.getId(), "DpK8sInstance", "id", k8sInstance.getId());
        String namespace = dpServerConfig.getK8sNameSpace();

        String podName = dpServer.getName();
        String logContent = k8sService.getDeploymentLog(k8sInstance, namespace, podName);

        return logContent;
    }

    @Override
    public boolean healthCheck(Integer projectId, String env) {
        DpServerConfig dpServerConfig = dpServerConfigRepository.findFirstByProjectIdAndEnv(projectId, env);
        if (dpServerConfig == null || StringUtils.isEmpty(dpServerConfig.getK8sNameSpace())) {
            throw new BadRequestException("请配置服务所部署的集群");
        }

        DpServer dpServer = dpServerRepository.findById(projectId.longValue()).get();
        if (dpServer == null) {
            throw new BadRequestException("找不到项目：id:" + projectId);
        }

        Integer k8sIntanceId = dpServerConfig.getK8sInstanceId();
        DpK8sInstance k8sInstance = dpK8sInstanceRepository.findById(k8sIntanceId).orElseGet(DpK8sInstance::new);
        ValidationUtil.isNull(k8sInstance.getId(), "DpK8sInstance", "id", k8sInstance.getId());
        String namespace = dpServerConfig.getK8sNameSpace();

        String podName = dpServer.getName();
        return k8sService.healthCheck(k8sInstance, namespace, podName);
    }

    @Override
    public void rollbackBranch(PublishSheetFlowDto flowDto, String env) {
        List<PublishProjectDto> projectDtoList = flowDto.getPublishProjects().stream().collect(Collectors.toList());

        // 获取流程发布者的gittoken
        Long applierId = flowDto.getApplierId();
        UserDto userDto = userService.findById(applierId);
        String gitlabToken = userDto.getGitlabToken();
        if(StringUtils.isEmpty(gitlabToken)) {
            throw new BadRequestException("申请者(" + userDto.getNickName() + ")的账号未设置gitlab的token");
        }

        int projectLen = projectDtoList.size();
        for(int index = 0; index < projectLen; index++) {
            PublishProjectDto publishProjectDto = projectDtoList.get(index);
            Integer projectId = publishProjectDto.getProjectId().intValue();
            String sourceBranch = publishProjectDto.getBranch();

            try {
                gitlabService.rollbackBranch(gitlabToken, sourceBranch, env, projectId);
            } catch (GitLabApiException e) {
                e.printStackTrace();
                throw new BadRequestException(e.getMessage());
            }
        }
    }

    @Override
    public void deleteBranch(PublishSheetFlowDto flowDto, String env) {
        List<PublishProjectDto> projectDtoList = flowDto.getPublishProjects().stream().collect(Collectors.toList());

        // 获取流程发布者的gittoken
        Long applierId = flowDto.getApplierId();
        UserDto userDto = userService.findById(applierId);
        String gitlabToken = userDto.getGitlabToken();
        if(StringUtils.isEmpty(gitlabToken)) {
            throw new BadRequestException("申请者(" + userDto.getNickName() + ")的账号未设置gitlab的token");
        }

        int projectLen = projectDtoList.size();
        for(int index = 0; index < projectLen; index++) {
            PublishProjectDto publishProjectDto = projectDtoList.get(index);
            Integer projectId = publishProjectDto.getProjectId().intValue();
            String sourceBranch = publishProjectDto.getBranch();

            try {
                gitlabService.deleteBranch(gitlabToken, projectId, env, sourceBranch);
            } catch (GitLabApiException e) {
                e.printStackTrace();
                throw new BadRequestException(e.getMessage());
            }
        }
    }
}
